package com.wlyuan.index.domain.source.adapter;

import com.wlyuan.index.api.dto.combine.CombineIndexDTO;
import com.wlyuan.transport.dto.query.CombineCustomerDTO;
import com.wlyuan.transport.dto.query.CombineDetailDTO;
import com.wlyuan.transport.dto.query.WaybillDetailDTO;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * @author yuanjie
 */
@EqualsAndHashCode(callSuper = true)
@Data
public class CombineAdapter extends CombineIndexDTO implements Serializable {
    @Mapper
    public interface Assembler {
        void assemble(@MappingTarget CombineIndexDTO target, CombineIndexDTO source);

        CombineIndexDTO translate(CombineDetailDTO source);

        @Mappings({
                @Mapping(source = "customer", target = "."),
                @Mapping(source = "consignee", target = ".")
        })
        CombineIndexDTO.Waybill assembleWaybill(WaybillDetailDTO source);
    }

    private static final Assembler ASSEMBLER = Mappers.getMapper(Assembler.class);

    public CombineAdapter(CombineIndexDTO index) {
        ASSEMBLER.assemble(this, index);
    }

    public static CombineIndexDTO translate(CombineDetailDTO source) {
        return ASSEMBLER.translate(source);
    }

    public List<String> getKeywords() {
        List<String> keywords = new ArrayList<>();
        if (StringUtils.isNotEmpty(this.getContractNo())) {
            keywords.add(this.getContractNo());
        }

        Optional.ofNullable(this.getCustomer())
                .map(CombineCustomerDTO::getCustomerName)
                .filter(StringUtils::isNotEmpty)
                .ifPresent(keywords::add);

        if (CollectionUtils.isNotEmpty(this.getWaybills())) {
            this.getWaybills().stream()
                    .map(Waybill::getContractNo)
                    .filter(StringUtils::isNotEmpty)
                    .forEach(keywords::add);
        }

        return keywords;
    }

}
